package scheduler


/**
	什么是scheduler？
	基本上形成了engine --提交任务（数据）-->scheduler --将任务分派给各个Worker -->Work将数据返回给Engine
	Scheduler在这个流程中充当了一个调度器的功能，调度Worker进行工作
 */


//定义行为
type Scheduler interface {
	Submit(string)
	Run()
	// 返回一个传输数据给worker的通道
	WorkerChan() chan string
	WorkerReady(chan string)
}


//SimpleScheduler

type SimpleScheduler struct {
	requestChan chan string
}

func (s *SimpleScheduler) WorkerReady(chan string) {
	panic("implement me")
}

func (s *SimpleScheduler) Submit(submit string) {
	//起一个go来提交任务给Worker们
	go func() {
		s.requestChan <- submit
	}()
}

func (s *SimpleScheduler) Run() {
	//启动调度器，make一个chanel
	s.requestChan = make(chan string)
}

func (s *SimpleScheduler) WorkerChan() chan string {
	return s.requestChan
}



//队列版的调度器
type QueueScheduler struct {
	requestChan chan string
	workerChan chan chan string
}

func (q *QueueScheduler) WorkerReady(w chan string) {
	//当worker就绪了可以进行下一个处理的时候，将其加入到workChan里去
	q.workerChan <- w
}

func (q *QueueScheduler) Submit(sub string) {
	q.requestChan <- sub
}

func (q *QueueScheduler) Run() {
	//先初始化两个chan
	q.requestChan = make(chan string)
	q.workerChan = make(chan chan string)
	go func() {
		var requestQ []string
		var workerQ []chan string

		for{
			var activeWorker chan string
			var activeRequest string
			if len(requestQ)>0 && len(workerQ)>0{
				//取出任务和worker
				activeRequest = requestQ[0]
				activeWorker = workerQ[0]
			}
			select {
				case r := <- q.requestChan:
					//取到任务了，加进队列去
					requestQ = append(requestQ, r)
				case w := <- q.workerChan:
					//取到工人了，加到工人队列去
					workerQ = append(workerQ,w)
				case activeWorker <- activeRequest:
					workerQ = workerQ[1:]
					requestQ = requestQ[1:]
			}
		}
	}()
}

func (q *QueueScheduler) WorkerChan() chan string {
	return make(chan string)
}
